﻿using System;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using Nop.Core;
using Nop.Core.Domain;
using Nop.Core.Domain.Orders;
using Nop.Plugin.Widgets.SpreadButton.Models;
using Nop.Services.Catalog;
using Nop.Services.Configuration;
using Nop.Services.Logging;
using Nop.Services.Orders;
using Nop.Web.Framework.Controllers;
using Nop.Services.Customers;
using Nop.Core.Domain.Customers;
using Nop.Core.Domain.Payments;
using Nop.Services.Messages;
using Nop.Core.Domain.Localization;
using Nop.Core.Domain.Messages;
using Nop.Core.Infrastructure;
using Nop.Services.Localization;
using Nop.Web.Framework.Security;
using Nop.Services.Security;
using Nop.Services.Authentication;
using Nop.Core.Domain.Security;
using System.Security;

namespace Nop.Plugin.Widgets.SpreadButton.Controllers
{
    public class WidgetSpreadButtonController : Controller
    {
        private readonly IWorkContext _workContext;
        private readonly IWebHelper _webHelper;
        private readonly ISettingService _settingService;
        private readonly IOrderService _orderService;
        private readonly ILogger _logger;
        private readonly ICategoryService _categoryService;
        private readonly IProductAttributeParser _productAttributeParser;
        private readonly SpreadButtonSettings _spreadButtonSettings;
        private readonly StoreInformationSettings _storeInformationSettings;
        private readonly IEmailAccountService _emailAccountService;
        private readonly EmailAccountSettings _emailAccountSettings;
        private readonly LocalizationSettings _localizationSettings;
        private readonly IGiftCardService _giftCardService;
        private readonly IWorkflowMessageService _workflowMessageService;
        private readonly ILocalizationService _localizationService;
        private readonly ICustomerActivityService _customerActivityService;
        private readonly IPermissionService _permissionService;
        private readonly IEncryptionService _encryptionService;
        private readonly ICustomerService _customerService;
        private readonly CustomerSettings _customerSettings;
        private readonly IAuthenticationService _authenticationService;

        public WidgetSpreadButtonController(IWorkContext workContext, IWebHelper webHelper, ISettingService settingService,
            IOrderService orderService, ILogger logger,
            ICategoryService categoryService, IProductAttributeParser productAttributeParser,
            SpreadButtonSettings trackingScriptsSettings, StoreInformationSettings storeInformationSettings,
            IEmailAccountService emailAccountService,
            EmailAccountSettings emailAccountSettings,
            LocalizationSettings localizationSettings,
            IGiftCardService giftCardService,
            IWorkflowMessageService workflowMessageService,
            ILocalizationService localizationService,
            ICustomerActivityService customerActivityService,
            IPermissionService permissionService,
            IEncryptionService encryptionService,
            ICustomerService customerService,
            CustomerSettings customerSettings,
            IAuthenticationService authenticationService)
        {
            this._workContext = workContext;
            this._webHelper = webHelper;
            this._settingService = settingService;
            this._orderService = orderService;
            this._logger = logger;
            this._categoryService = categoryService;
            this._productAttributeParser = productAttributeParser;
            this._spreadButtonSettings = trackingScriptsSettings;
            this._storeInformationSettings = storeInformationSettings;
            this._emailAccountService = emailAccountService;
            this._emailAccountSettings = emailAccountSettings;
            this._localizationSettings = localizationSettings;
            this._giftCardService = giftCardService;
            this._workflowMessageService = workflowMessageService;
            this._localizationService = localizationService;
            this._customerActivityService = customerActivityService;
            this._permissionService = permissionService;
            this._encryptionService = encryptionService;
            this._customerService = customerService;
            this._customerSettings = customerSettings;
            this._authenticationService = authenticationService;

            System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
        }

        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure()
        {
            var model = new ConfigurationModel();
            model.PublicApiKey = _spreadButtonSettings.PublicApiKey;
            model.PrivateApiKey = _spreadButtonSettings.PrivateApiKey;
            model.TrackingScript = _spreadButtonSettings.TrackingScript;

            model.ZoneId = _spreadButtonSettings.WidgetZone;
            model.AvailableZones.Add(new SelectListItem() { Text = "<head> HTML tag", Value = "head_html_tag" });
            model.AvailableZones.Add(new SelectListItem() { Text = "Before <body> end HTML tag", Value = "body_end_html_tag_before" });

            return View("Nop.Plugin.Widgets.SpreadButton.Views.WidgetSpreadButton.Configure", model);
        }

        [HttpPost]
        [AdminAuthorize]
        [ChildActionOnly]
        public ActionResult Configure(ConfigurationModel model)
        {
            if (!ModelState.IsValid)
                return Configure();

            //save settings
            _spreadButtonSettings.PublicApiKey = model.PublicApiKey;
            _spreadButtonSettings.PrivateApiKey = model.PrivateApiKey;
            _spreadButtonSettings.TrackingScript = model.TrackingScript;
            _spreadButtonSettings.WidgetZone = model.ZoneId;
            _settingService.SaveSetting(_spreadButtonSettings);

            return Configure();
        }

        [ChildActionOnly]
        public ActionResult PublicInfo(string widgetZone)
        {
            string globalScript = "";

            try
            {
                globalScript += GetTrackingScript();
            }
            catch (Exception ex)
            {
                _logger.InsertLog(Core.Domain.Logging.LogLevel.Error, "Error creating scripts for spreadButton ecommerce tracking", ex.ToString());
            }
            return Content(globalScript);
        }

        //</script>
        private string GetTrackingScript()
        {
            string spreadButtonTrackingScript = "";
            spreadButtonTrackingScript = _spreadButtonSettings.TrackingScript + "\n";
            spreadButtonTrackingScript = spreadButtonTrackingScript.Replace("{PUBLICAPIKEY}", _spreadButtonSettings.PublicApiKey);
            return spreadButtonTrackingScript;
        }


        [Serializable]
        public class CreateGiftCardModel
        {
            public string login { get; set; }
            public string password { get; set; }
            public string customer_email { get; set; }
            public string customer_firstname { get; set; }
            public string customer_name { get; set; }
            public string action_discount_code { get; set; }
            public string campaign_name { get; set; }
            public decimal campaign_current_value { get; set; }
            public string campaign_currency { get; set; }
            public bool notify_customer { get; set; }
        }

        [HttpPost]
        [NopHttpsRequirement(SslRequirement.Yes)]
        [ValidateInput(false)]
        public ActionResult CreateGiftCard(CreateGiftCardModel model)
        {
            try
            {
                CheckAccess(model.login, model.password, StandardPermissionProvider.ManageGiftCards);


                if (model.campaign_currency != "EUR")
                {
                    throw new ApplicationException("Currency not supported");
                }

                var emailAccount = _emailAccountService.GetEmailAccountById(_emailAccountSettings.DefaultEmailAccountId);
                if (emailAccount == null)
                    emailAccount = _emailAccountService.GetAllEmailAccounts().FirstOrDefault();

                var giftCard = new GiftCard();
                giftCard.IsGiftCardActivated = true;
                giftCard.SenderName = emailAccount.DisplayName;
                giftCard.SenderEmail = emailAccount.Email;
                giftCard.RecipientName = model.customer_firstname + " " + model.customer_name;
                giftCard.RecipientEmail = model.customer_email;
                giftCard.Amount = model.campaign_current_value;
                giftCard.Message = model.campaign_name;
                giftCard.GiftCardCouponCode = model.action_discount_code;

                giftCard.CreatedOnUtc = DateTime.UtcNow;
                _giftCardService.InsertGiftCard(giftCard);

                if (model.notify_customer)
                {
                    int queuedEmailId = _workflowMessageService.SendGiftCardNotification(giftCard, _localizationSettings.DefaultAdminLanguageId);
                    if (queuedEmailId > 0)
                    {
                        giftCard.IsRecipientNotified = true;
                        _giftCardService.UpdateGiftCard(giftCard);
                    }
                }


                //activity log
                _customerActivityService.InsertActivity("AddNewGiftCard", _localizationService.GetResource("ActivityLog.AddNewGiftCard"), giftCard.GiftCardCouponCode);


                //nothing should be rendered to visitor
                return Json(new { Success = true });

            }
            catch (SecurityException sex)
            {
                Response.StatusCode = 403;
                Response.TrySkipIisCustomErrors = true;
                return Json(new { Success = false, Message = sex.Message });
            }
            catch (Exception ex)
            {
                Response.StatusCode = 500;
                Response.TrySkipIisCustomErrors = true;
                return Json(new { Success = false, Message = ex.Message });
            }

        }


        public void CheckAccess(string usernameOrEmail, string userPassword, PermissionRecord permission)
        {

            if (!System.Web.HttpContext.Current.User.Identity.IsAuthenticated)
            {
                Customer customer = null;
                if (_customerSettings.UsernamesEnabled)
                    customer = _customerService.GetCustomerByUsername(usernameOrEmail);
                else
                    customer = _customerService.GetCustomerByEmail(usernameOrEmail);

                if (customer == null || customer.Deleted || !customer.Active)
                    throw new SecurityException("Not allowed");

                string pwd = string.Empty;
                switch (customer.PasswordFormat)
                {
                    case PasswordFormat.Encrypted:
                        pwd = _encryptionService.EncryptText(userPassword);
                        break;
                    case PasswordFormat.Hashed:
                        pwd = _encryptionService.CreatePasswordHash(userPassword, customer.PasswordSalt, _customerSettings.HashedPasswordFormat);
                        break;
                    default:
                        pwd = userPassword;
                        break;
                }

                bool isValid = pwd == customer.Password;
                if (!isValid)
                    throw new SecurityException("Not allowed");

                //TODO surprising....
                _workContext.CurrentCustomer = customer;
                _authenticationService.SignIn(customer, true);

                if (!_permissionService.Authorize(permission))
                    throw new SecurityException("Not allowed to Manage gift cards");
            }

        }


    }
}